﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.JointJog.CUiKinJointJogDeviceNodeData
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using UiInternalControls.WindowsFormsControls;


namespace DnProcessSimulateCommands.JointJog;

public class CUiKinJointJogDeviceNodeData : CUiKinJointJogNodeData
{
  private ComboBox _posesListControl = new ComboBox();
  private List<CUiKinJointJogNodeData> m_childrenNodes = new List<CUiKinJointJogNodeData>();
  private TxObjectList _registeredPoses = new TxObjectList();
  private Dictionary<string, ITxDevice> m_otherDevice = new Dictionary<string, ITxDevice>();
  private bool m_registeredForSelectedIndexChanged;

  public event CUiKinJointJogDeviceNodeData.CUiKinJointJogDeviceNodeDataJointChangedHandler JointChanged;

  public CUiKinJointJogDeviceNodeData(CApKinJointJogApp jointJogApplication, ITxDevice device)
    : base(jointJogApplication, (ITxObject) device, (Image) null, ((ITxObject) device).Name)
  {
    this.m_nodeIcon = CApKinJointJogApp.GetObjectImage((ITxObject) device);
    this._posesListControl.DropDownStyle = ComboBoxStyle.DropDownList;
    this._posesListControl.Visible = false;
    this._posesListControl.Items.Add((object) "");
    foreach (TxPose pose in (Collection<ITxObject>) this.Device.PoseList)
      this._posesListControl.Items.Add((object) pose.Name);
    this.AddJoints();
    this.AddChildren();
    this.RegisterForEvents();
  }

  public ITxDevice Device => this.NodeObject as ITxDevice;

  public ComboBox PosesListControl => this._posesListControl;

  public List<CUiKinJointJogNodeData> ChildrenNodes => this.m_childrenNodes;

  public IEnumerable<CUiKinJointJogJointNodeData> Joints
  {
    get
    {
      foreach (CUiKinJointJogNodeData childrenNode in this.m_childrenNodes)
      {
        if (childrenNode is CUiKinJointJogJointNodeData joint && !joint.Disposed)
          yield return joint;
      }
    }
  }

  public IEnumerable<CUiKinJointJogDeviceNodeData> ChildDevices
  {
    get
    {
      foreach (CUiKinJointJogNodeData childrenNode in this.m_childrenNodes)
      {
        if (childrenNode is CUiKinJointJogDeviceNodeData childDevice && !childDevice.Disposed)
          yield return childDevice;
      }
    }
  }

  private void nodeObject_KinematicMoved(object sender, TxDevice_KinematicMovedEventArgs args)
  {
    if (TxApplicationEx.PerformanceModeManager().InMode(new TxPerformanceModeEx((TxPerformanceModeType) 5)))
      return;
    foreach (CUiKinJointJogJointNodeData joint in this.Joints)
    {
      if (!this.m_jointJogApplication.IsAxisToRemove(joint.Joint))
      {
        joint.EnterControlsInitMode();
        bool flag = false;
        if (joint.HasVariableLimits())
        {
          joint.StartRefreshControls();
          flag = true;
        }
        if (!joint.Joint.IsDependent)
        {
          ITxDevice device = joint.Joint.Device;
          TxDevicePoseData txDevicePoseData = new TxDevicePoseData(device, device.CurrentPose);
          if (txDevicePoseData.DoesHaveJoint(joint.Joint))
          {
            double jointValue = txDevicePoseData.GetJointValue(joint.Joint);
            joint.JointValue = jointValue;
          }
        }
        else
          joint.RefreshControls();
        if (flag)
          joint.EndRefreshControls();
        joint.ExitControlsInitMode();
      }
    }
    this.UpdatePoseInPoseList();
  }

  private void ValueControl_ValueChanged(object sender, EventArgs e)
  {
    this.UpdatePoseInPoseList();
    if (this.JointChanged == null)
      return;
    this.JointChanged(sender, e);
  }

  private void SliderControl_ValueChanged(object sender, TxWheelControl_ValueChangedEventArgs e)
  {
    this.UpdatePoseInPoseList();
    if (this.JointChanged == null)
      return;
    EventArgs args = new EventArgs();
    this.JointChanged(sender, args);
  }

  private void SliderControl_DragWheelStart(object sender, EventArgs e)
  {
    TxApplication.ActiveUndoManager.StartTransaction();
  }

  private void SliderControl_DragWheelEnd(object sender, EventArgs e)
  {
    TxApplication.ActiveUndoManager.EndTransaction();
  }

  private void deviceData_JointChanged(object sender, EventArgs args)
  {
    this.UpdatePoseInPoseList();
    if (this.JointChanged == null)
      return;
    this.JointChanged(sender, args);
  }

  private void _posesListControl_SelectedIndexChanged(object sender, EventArgs e)
  {
    bool flag = this.UnregisterForPosesListSelectedIndexChanged();
    int selectedIndex = this._posesListControl.SelectedIndex;
    TxPose poseByName = this.GetPoseByName(this._posesListControl.Items[selectedIndex].ToString());
    if (TxPose.op_Inequality(poseByName, (ITxObject) null))
    {
      this.ChangeDevicePose(poseByName.PoseData);
      this._posesListControl.SelectedIndex = selectedIndex;
      TxApplication.RefreshDisplay();
    }
    if (this.JointChanged != null)
      this.JointChanged(sender, e);
    if (!flag)
      return;
    this.RegisterForPosesListSelectedIndexChanged();
  }

  private void PosesListControl_DropDown(object sender, EventArgs e)
  {
    string empty = string.Empty;
    int num1 = 0;
    if (this._posesListControl.SelectedIndex != -1)
      empty = this._posesListControl.SelectedItem.ToString();
    this._posesListControl.Items.Clear();
    this._posesListControl.Items.Add((object) string.Empty);
    foreach (TxPose pose in (Collection<ITxObject>) this.Device.PoseList)
    {
      int num2 = this._posesListControl.Items.Add((object) pose.Name);
      if (pose.Name == empty)
        num1 = num2;
    }
    bool flag = this.UnregisterForPosesListSelectedIndexChanged();
    this._posesListControl.SelectedIndex = num1;
    if (!flag)
      return;
    this.RegisterForPosesListSelectedIndexChanged();
  }

  public void UpdatePoseInPoseList()
  {
    foreach (CUiKinJointJogNodeData nodesData in this.m_jointJogApplication.NodesDataList)
    {
      if (nodesData is CUiKinJointJogDeviceNodeData jogDeviceNodeData)
        jogDeviceNodeData.InternalUpdatePoseInPoseList();
    }
  }

  private TxPose GetPoseByPoseData(TxPoseData poseData, TxObjectList posesList)
  {
    TxPose poseByPoseData = (TxPose) null;
    TxDevicePoseData txDevicePoseData1 = new TxDevicePoseData(this.Device, poseData);
    foreach (TxPose poses in (Collection<ITxObject>) posesList)
    {
      TxDevicePoseData txDevicePoseData2 = new TxDevicePoseData(this.Device, poses.PoseData);
      if (txDevicePoseData1.Equals((object) txDevicePoseData2))
      {
        poseByPoseData = poses;
        break;
      }
    }
    return poseByPoseData;
  }

  public void SetJointValue(TxJoint joint, double newValue)
  {
    if (CApKinJointJogApp.JointSpecific_AreEqualValues(joint.CurrentValue, newValue))
      return;
    this.Device.KinematicMoved -= new TxDevice_KinematicMovedEventHandler(this.nodeObject_KinematicMoved);
    this.UnregisterForOtherDevicesEvents();
    try
    {
      joint.CurrentValue = newValue;
    }
    catch (TxJointSetValueFailedException ex)
    {
    }
    this.Device.KinematicMoved += new TxDevice_KinematicMovedEventHandler(this.nodeObject_KinematicMoved);
    this.RegisterForOtherDevicesEvents();
  }

  public void ChangeDevicePose(TxPoseData poseData) => this.Device.CurrentPose = poseData;

  private void AddJoints()
  {
    foreach (TxJoint drivingJoint in (Collection<ITxObject>) this.Device.DrivingJoints)
      this.m_childrenNodes.Add((CUiKinJointJogNodeData) this.m_jointJogApplication.GetJointNodeData(drivingJoint, this, this.Device));
    foreach (TxJoint joint in (Collection<ITxObject>) this.Device.AllJointsAfterCompilation)
    {
      if (joint.IsDependent)
        this.m_childrenNodes.Add((CUiKinJointJogNodeData) this.m_jointJogApplication.GetJointNodeData(joint, this, this.Device));
    }
    TxRobot nodeObject = this.NodeObject as TxRobot;
    if (!TxRobot.op_Inequality(nodeObject, (ITxObject) null))
      return;
    foreach (TxJoint filterRemovedAx in (Collection<ITxObject>) this.m_jointJogApplication.FilterRemovedAxes((ITxRobot) nodeObject))
    {
      CUiKinJointJogJointNodeData jointNodeData = this.m_jointJogApplication.GetJointNodeData(filterRemovedAx, this, this.Device, true);
      jointNodeData.NiceName = $"{jointNodeData.Joint.Name} ({((ITxObject) jointNodeData.Joint.Device).Name})";
      this.m_childrenNodes.Add((CUiKinJointJogNodeData) jointNodeData);
      ITxDevice deviceOfJoint = this.GetDeviceOfJoint(filterRemovedAx);
      if (!this.m_otherDevice.ContainsKey(((ITxObject) deviceOfJoint).Id))
        this.m_otherDevice.Add(((ITxObject) deviceOfJoint).Id, deviceOfJoint);
    }
  }

  private ITxDevice GetDeviceOfJoint(TxJoint joint)
  {
    ITxDevice deviceOfJoint = (ITxDevice) null;
    TxKinematicLink childLink = joint.ChildLink;
    if (TxKinematicLink.op_Inequality(childLink, (ITxObject) null))
    {
      ITxObjectCollection collection = childLink.Collection;
      if (collection != null)
        deviceOfJoint = collection as ITxDevice;
    }
    return deviceOfJoint;
  }

  private void AddChildren()
  {
    if (!(this.NodeObject is ITxObjectCollection nodeObject))
      return;
    TxTypeFilter txTypeFilter1 = new TxTypeFilter(typeof (ITxComponent));
    foreach (ITxComponent directDescendant in (Collection<ITxObject>) nodeObject.GetDirectDescendants((ITxTypeFilter) txTypeFilter1))
    {
      if (directDescendant is ITxDevice device)
        this.m_childrenNodes.Add((CUiKinJointJogNodeData) this.m_jointJogApplication.GetDeviceNodeData(device));
      else if (directDescendant is ITxObjectCollection objectCollection)
      {
        TxTypeFilter txTypeFilter2 = new TxTypeFilter(typeof (ITxDevice));
        if (((Collection<ITxObject>) objectCollection.GetAllDescendants((ITxTypeFilter) txTypeFilter2)).Count > 0)
          this.m_childrenNodes.Add((CUiKinJointJogNodeData) this.m_jointJogApplication.GetComponentNodeData(directDescendant));
      }
    }
  }

  private void RegisterForOtherDevicesEvents()
  {
    foreach (KeyValuePair<string, ITxDevice> keyValuePair in this.m_otherDevice)
      keyValuePair.Value.KinematicMoved += new TxDevice_KinematicMovedEventHandler(this.device_KinematicMoved);
  }

  private void UnregisterForOtherDevicesEvents()
  {
    foreach (KeyValuePair<string, ITxDevice> keyValuePair in this.m_otherDevice)
      keyValuePair.Value.KinematicMoved -= new TxDevice_KinematicMovedEventHandler(this.device_KinematicMoved);
  }

  private void device_KinematicMoved(object sender, TxDevice_KinematicMovedEventArgs args)
  {
    this.nodeObject_KinematicMoved(sender, args);
  }

  private void RegisterForEvents()
  {
    foreach (CUiKinJointJogJointNodeData joint in this.Joints)
    {
      joint.SliderControl.ValueChanged += new TxWheelControl.TxWheelControl_ValueChangedEventHandler(this.SliderControl_ValueChanged);
      joint.SliderControl.DragWheelStart += new TxWheelControl.TxWheelControl_DragWheelEventHandler(this.SliderControl_DragWheelStart);
      joint.SliderControl.DragWheelEnd += new TxWheelControl.TxWheelControl_DragWheelEventHandler(this.SliderControl_DragWheelEnd);
      joint.ValueControl.ValueChanged += new EventHandler(this.ValueControl_ValueChanged);
    }
    foreach (CUiKinJointJogDeviceNodeData childDevice in this.ChildDevices)
      childDevice.JointChanged += new CUiKinJointJogDeviceNodeData.CUiKinJointJogDeviceNodeDataJointChangedHandler(this.deviceData_JointChanged);
    this.RegisterForOtherDevicesEvents();
    this.Device.KinematicMoved += new TxDevice_KinematicMovedEventHandler(this.nodeObject_KinematicMoved);
    this.RegisterForPoseEvents();
    this.PosesListControl.DropDown += new EventHandler(this.PosesListControl_DropDown);
    this.RegisterForPosesListSelectedIndexChanged();
  }

  private void UnregisterForEvents()
  {
    foreach (CUiKinJointJogJointNodeData joint in this.Joints)
    {
      joint.SliderControl.ValueChanged -= new TxWheelControl.TxWheelControl_ValueChangedEventHandler(this.SliderControl_ValueChanged);
      joint.SliderControl.DragWheelStart -= new TxWheelControl.TxWheelControl_DragWheelEventHandler(this.SliderControl_DragWheelStart);
      joint.SliderControl.DragWheelEnd -= new TxWheelControl.TxWheelControl_DragWheelEventHandler(this.SliderControl_DragWheelEnd);
      joint.ValueControl.ValueChanged -= new EventHandler(this.ValueControl_ValueChanged);
    }
    foreach (CUiKinJointJogDeviceNodeData childDevice in this.ChildDevices)
      childDevice.JointChanged -= new CUiKinJointJogDeviceNodeData.CUiKinJointJogDeviceNodeDataJointChangedHandler(this.deviceData_JointChanged);
    this.UnregisterForOtherDevicesEvents();
    this.Device.KinematicMoved -= new TxDevice_KinematicMovedEventHandler(this.nodeObject_KinematicMoved);
    this.UnRegisterForPoseEvents();
    this.PosesListControl.DropDown -= new EventHandler(this.PosesListControl_DropDown);
    this.UnregisterForPosesListSelectedIndexChanged();
  }

  private bool RegisterForPosesListSelectedIndexChanged()
  {
    bool flag = false;
    if (!this.m_registeredForSelectedIndexChanged)
    {
      this.PosesListControl.SelectedIndexChanged += new EventHandler(this._posesListControl_SelectedIndexChanged);
      this.m_registeredForSelectedIndexChanged = true;
      flag = true;
    }
    return flag;
  }

  private bool UnregisterForPosesListSelectedIndexChanged()
  {
    bool flag = false;
    if (this.m_registeredForSelectedIndexChanged)
    {
      this.PosesListControl.SelectedIndexChanged -= new EventHandler(this._posesListControl_SelectedIndexChanged);
      this.m_registeredForSelectedIndexChanged = false;
      flag = true;
    }
    return flag;
  }

  private TxPose GetPoseByName(string poseName)
  {
    TxPose poseByName = (TxPose) null;
    foreach (TxPose pose in (Collection<ITxObject>) this.Device.PoseList)
    {
      if (poseName == pose.Name)
      {
        poseByName = pose;
        break;
      }
    }
    return poseByName;
  }

  private void InternalUpdatePoseInPoseList()
  {
    bool flag = this.UnregisterForPosesListSelectedIndexChanged();
    if (this._posesListControl.Enabled)
    {
      TxPose poseByPoseData = this.GetPoseByPoseData(this.Device.CurrentPose, this.Device.PoseList);
      if (TxPose.op_Inequality(poseByPoseData, (ITxObject) null))
        this._posesListControl.SelectedItem = (object) poseByPoseData.Name;
      else
        this._posesListControl.SelectedIndex = 0;
    }
    if (!flag)
      return;
    this.RegisterForPosesListSelectedIndexChanged();
  }

  private void RefreshPoseList(TxPose selectedPose, TxObjectList posesList)
  {
    this._posesListControl.Items.Clear();
    this._posesListControl.Items.Add((object) string.Empty);
    foreach (TxPose poses in (Collection<ITxObject>) posesList)
      this._posesListControl.Items.Add((object) poses.Name);
    bool flag = this.UnregisterForPosesListSelectedIndexChanged();
    if (TxPose.op_Inequality(selectedPose, (ITxObject) null))
      this._posesListControl.SelectedItem = (object) selectedPose.Name;
    else
      this._posesListControl.SelectedIndex = 0;
    if (!flag)
      return;
    this.RegisterForPosesListSelectedIndexChanged();
  }

  private void RegisterForPoseEvents()
  {
    this.Device.PoseCreated += new TxDevice_PoseCreatedEventHandler(this.device_PoseCreated);
    foreach (TxPose pose in (Collection<ITxObject>) this.Device.PoseList)
    {
      if (!((Collection<ITxObject>) this._registeredPoses).Contains((ITxObject) pose))
      {
        this.RegisterForPoseEvents(pose);
        ((Collection<ITxObject>) this._registeredPoses).Add((ITxObject) pose);
      }
    }
  }

  private void UnRegisterForPoseEvents()
  {
    this.Device.PoseCreated -= new TxDevice_PoseCreatedEventHandler(this.device_PoseCreated);
    foreach (TxPose registeredPose in (Collection<ITxObject>) this._registeredPoses)
      this.UnRegisterForPoseEvents(registeredPose);
    ((Collection<ITxObject>) this._registeredPoses).Clear();
  }

  private void RegisterForPoseEvents(TxPose pose)
  {
    pose.Deleted += new TxObject_DeletedEventHandler(this.devicePose_Deleted);
    pose.NameChanged += new TxObject_NameChangedEventHandler(this.devicePose_NameChanged);
    pose.PoseDataChanged += new TxPose_PoseDataChangedEventHandler(this.devicePose_PoseDataChanged);
  }

  private void UnRegisterForPoseEvents(TxPose pose)
  {
    pose.Deleted -= new TxObject_DeletedEventHandler(this.devicePose_Deleted);
    pose.NameChanged -= new TxObject_NameChangedEventHandler(this.devicePose_NameChanged);
    pose.PoseDataChanged -= new TxPose_PoseDataChangedEventHandler(this.devicePose_PoseDataChanged);
  }

  private void device_PoseCreated(object sender, TxDevice_PoseCreatedEventArgs args)
  {
    TxObjectList poseList = this.Device.PoseList;
    this.RefreshPoseList(this.GetPoseByPoseData(this.Device.CurrentPose, poseList), poseList);
    this.RegisterForPoseEvents(args.Pose);
  }

  private void devicePose_Deleted(object sender, TxObject_DeletedEventArgs args)
  {
    TxPose pose = sender as TxPose;
    TxObjectList poseList = this.Device.PoseList;
    if (((Collection<ITxObject>) poseList).Contains((ITxObject) pose))
      ((Collection<ITxObject>) poseList).Remove((ITxObject) pose);
    this.RefreshPoseList(this.GetPoseByPoseData(this.Device.CurrentPose, poseList), poseList);
    this.UnRegisterForPoseEvents(pose);
  }

  private void devicePose_NameChanged(object sender, TxObject_NameChangedEventArgs args)
  {
    TxObjectList poseList = this.Device.PoseList;
    this.RefreshPoseList(this.GetPoseByPoseData(this.Device.CurrentPose, poseList), poseList);
  }

  private void devicePose_PoseDataChanged(object sender, TxPose_PoseDataChangedEventArgs args)
  {
    TxObjectList poseList = this.Device.PoseList;
    this.RefreshPoseList(this.GetPoseByPoseData(this.Device.CurrentPose, poseList), poseList);
  }

  public override void Dispose()
  {
    if (this.m_disposed)
      return;
    this.UnregisterForEvents();
    this.m_disposed = true;
    base.Dispose();
  }

  public delegate void CUiKinJointJogDeviceNodeDataJointChangedHandler(
    object sender,
    EventArgs args);
}
